<?php

namespace app\controller;

use support\Request;
use support\Response;
use GuzzleHttp\Client;

class ApiController
{
    private $feishuConfig;
    private $httpClient;

    const TENANT_ACCESS_TOKEN_URL = 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal';
    const UPLOAD_URL = 'https://open.feishu.cn/open-apis/drive/v1/medias/upload_all';
    const BITABLE_ADD_RECORD_URL = 'https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records';

    public function __construct()
    {
        $this->feishuConfig = config('feishu');
        $this->httpClient = new Client();
    }

    public function submit(Request $request)
    {
        $session = $request->session();
        if (!$session->has('user_info')) {
            return new Response(401, [], json_encode(['code' => 401, 'message' => 'Unauthorized']));
        }

        $data = $request->post();
        $file = $request->file('proof_file');
        $userInfo = $session->get('user_info');
        
        if (!$file || !$file->isValid()) {
            return new Response(400, [], json_encode(['code' => 400, 'message' => 'File not uploaded or invalid.']));
        }

        try {
            $tenantAccessToken = $this->getTenantAccessToken();

            $fileToken = $this->uploadFile($tenantAccessToken, $file);

            $this->addBitableRecord($tenantAccessToken, [
                'applicant_name' => $userInfo['name'],
                'applicant_department' => implode(', ', $userInfo['department_ids'] ?? []), // 注意：user_info中可能没有部门ID，需要确认权限和返回字段
                'reason' => $data['reason'],
                'relation' => $data['relation'],
                'proof_materials' => [['file_token' => $fileToken]],
            ]);

            return new Response(200, ['Content-Type' => 'application/json'], json_encode(['code' => 0, 'message' => 'Application submitted successfully.']));

        } catch (\Exception $e) {
            // Log error in production
            return new Response(500, ['Content-Type' => 'application/json'], json_encode(['code' => 500, 'message' => $e->getMessage()]));
        }
    }

    private function getTenantAccessToken()
    {
        // 可增加缓存逻辑，避免频繁获取
        $response = $this->httpClient->post(self::TENANT_ACCESS_TOKEN_URL, [
            'json' => [
                'app_id' => $this->feishuConfig['app_id'],
                'app_secret' => $this->feishuConfig['app_secret'],
            ],
        ]);

        $data = json_decode($response->getBody()->getContents(), true);
        if ($data['code'] !== 0) {
            throw new \Exception('Failed to get tenant_access_token: ' . $data['msg']);
        }
        return $data['tenant_access_token'];
    }

    private function uploadFile($token, $file)
    {
        $filePath = $file->getRealPath();
        $fileName = $file->getUploadName();

        $response = $this->httpClient->post(self::UPLOAD_URL, [
            'headers' => ['Authorization' => 'Bearer ' . $token],
            'multipart' => [
                [
                    'name' => 'file',
                    'contents' => fopen($filePath, 'r'),
                    'filename' => $fileName,
                ],
                ['name' => 'file_name', 'contents' => $fileName],
                ['name' => 'parent_type', 'contents' => 'bitable_file'],
                ['name' => 'parent_node', 'contents' => $this->feishuConfig['bitable_app_token']],
                ['name' => 'size', 'contents' => filesize($filePath)],
            ],
        ]);

        $data = json_decode($response->getBody()->getContents(), true);
        if ($data['code'] !== 0) {
            throw new \Exception('Failed to upload file: ' . ($data['msg'] ?? 'Unknown error'));
        }
        return $data['data']['file_token'];
    }

    private function addBitableRecord($token, $fields)
    {
        $url = str_replace(
            ['{app_token}', '{table_id}'],
            [$this->feishuConfig['bitable_app_token'], $this->feishuConfig['bitable_table_id']],
            self::BITABLE_ADD_RECORD_URL
        );

        $response = $this->httpClient->post($url, [
            'headers' => ['Authorization' => 'Bearer ' . $token],
            'json' => ['fields' => $fields],
        ]);

        $data = json_decode($response->getBody()->getContents(), true);
        if ($data['code'] !== 0) {
            throw new \Exception('Failed to add bitable record: ' . ($data['msg'] ?? 'Unknown error'));
        }
    }
} 